GParamSpec *pspec);
static void queue_update (GtkUIManager *self);
static void dirty_all_nodes (GtkUIManager *self);
+static void mark_node_dirty (GNode *node);
static GNode * get_child_node (GtkUIManager *self,
GNode *parent,
const gchar *childname,
NodeType node_type,
gboolean create);
static gboolean free_node (GNode *node);
-static void node_prepend_ui_reference (Node *node,
+static void node_prepend_ui_reference (GNode *node,
guint merge_id,
GQuark action_quark);
-static void node_remove_ui_reference (Node *node,
+static void node_remove_ui_reference (GNode *node,
guint merge_id);
merge_id = gtk_ui_manager_new_merge_id (self);
node = get_child_node (self, NULL, "ui", 2,
NODE_TYPE_ROOT, TRUE, FALSE);
- node_prepend_ui_reference (NODE_INFO (node), merge_id, 0);
+ node_prepend_ui_reference (node, merge_id, 0);
}
static void
mnode = g_chunk_new0 (Node, merge_node_chunk);
mnode->type = node_type;
mnode->name = g_strndup (childname, childname_length);
- mnode->dirty = TRUE;
if (top)
child = g_node_prepend_data (parent, mnode);
else
child = g_node_append_data (parent, mnode);
+
+ mark_node_dirty (child);
}
}
else
}
static void
-node_prepend_ui_reference (Node *node,
+node_prepend_ui_reference (GNode *gnode,
guint merge_id,
GQuark action_quark)
{
- NodeUIReference *reference;
+ Node *node = NODE_INFO (gnode);
+ NodeUIReference *reference = NULL;
- reference = g_new (NodeUIReference, 1);
- reference->action_quark = action_quark;
- reference->merge_id = merge_id;
+ if (node->uifiles &&
+ ((NodeUIReference *)node->uifiles->data)->merge_id == merge_id)
+ reference = node->uifiles->data;
+ else
+ {
+ reference = g_new (NodeUIReference, 1);
+ node->uifiles = g_list_prepend (node->uifiles, reference);
+ }
- /* Prepend the reference */
- node->uifiles = g_list_prepend (node->uifiles, reference);
+ reference->merge_id = merge_id;
+ reference->action_quark = action_quark;
- node->dirty = TRUE;
+ mark_node_dirty (gnode);
}
static void
-node_remove_ui_reference (Node *node,
+node_remove_ui_reference (GNode *gnode,
guint merge_id)
{
+ Node *node = NODE_INFO (gnode);
GList *p;
for (p = node->uifiles; p != NULL; p = p->next)
if (reference->merge_id == merge_id)
{
+ if (p == node->uifiles)
+ mark_node_dirty (gnode);
node->uifiles = g_list_delete_link (node->uifiles, p);
- node->dirty = TRUE;
g_free (reference);
break;
if (NODE_INFO (ctx->current)->action_name == 0)
NODE_INFO (ctx->current)->action_name = action_quark;
- node_prepend_ui_reference (NODE_INFO (ctx->current),
- ctx->merge_id, action_quark);
- NODE_INFO (ctx->current)->dirty = TRUE;
+ node_prepend_ui_reference (ctx->current, ctx->merge_id, action_quark);
raise_error = FALSE;
}
ctx->current = self->private_data->root_node;
raise_error = FALSE;
- node_prepend_ui_reference (NODE_INFO (ctx->current),
- ctx->merge_id, action_quark);
+ node_prepend_ui_reference (ctx->current, ctx->merge_id, action_quark);
}
break;
case 'm':
if (NODE_INFO (ctx->current)->action_name == 0)
NODE_INFO (ctx->current)->action_name = action_quark;
- node_prepend_ui_reference (NODE_INFO (ctx->current),
- ctx->merge_id, action_quark);
- NODE_INFO (ctx->current)->dirty = TRUE;
+ node_prepend_ui_reference (ctx->current, ctx->merge_id, action_quark);
+ mark_node_dirty (ctx->current);
raise_error = FALSE;
}
if (NODE_INFO (ctx->current)->action_name == 0)
NODE_INFO (ctx->current)->action_name = action_quark;
- node_prepend_ui_reference (NODE_INFO (ctx->current),
- ctx->merge_id, action_quark);
- NODE_INFO (ctx->current)->dirty = TRUE;
+ node_prepend_ui_reference (ctx->current, ctx->merge_id, action_quark);
raise_error = FALSE;
}
if (NODE_INFO (node)->action_name == 0)
NODE_INFO (node)->action_name = action_quark;
- node_prepend_ui_reference (NODE_INFO (node),
- ctx->merge_id, action_quark);
- NODE_INFO (node)->dirty = TRUE;
+ node_prepend_ui_reference (node, ctx->merge_id, action_quark);
raise_error = FALSE;
}
if (NODE_INFO (ctx->current)->action_name == 0)
NODE_INFO (ctx->current)->action_name = action_quark;
- node_prepend_ui_reference (NODE_INFO (ctx->current),
- ctx->merge_id, action_quark);
- NODE_INFO (ctx->current)->dirty = TRUE;
+ node_prepend_ui_reference (ctx->current, ctx->merge_id, action_quark);
raise_error = FALSE;
}
NODE_TYPE_MENU_PLACEHOLDER,
TRUE, top);
- node_prepend_ui_reference (NODE_INFO (ctx->current),
- ctx->merge_id, action_quark);
- NODE_INFO (ctx->current)->dirty = TRUE;
+ node_prepend_ui_reference (ctx->current, ctx->merge_id, action_quark);
raise_error = FALSE;
}
if (NODE_INFO (node)->action_name == 0)
NODE_INFO (node)->action_name = action_quark;
- node_prepend_ui_reference (NODE_INFO (node),
- ctx->merge_id, action_quark);
- NODE_INFO (node)->dirty = TRUE;
+ node_prepend_ui_reference (node, ctx->merge_id, action_quark);
raise_error = FALSE;
}
if (NODE_INFO (ctx->current)->action_name == 0)
NODE_INFO (ctx->current)->action_name = action_quark;
- node_prepend_ui_reference (NODE_INFO (ctx->current),
- ctx->merge_id, action_quark);
- NODE_INFO (ctx->current)->dirty = TRUE;
+ node_prepend_ui_reference (ctx->current, ctx->merge_id, action_quark);
raise_error = FALSE;
}
if (NODE_INFO (node)->action_name == 0)
NODE_INFO (node)->action_name = action_quark;
- node_prepend_ui_reference (NODE_INFO (node),
- ctx->merge_id, action_quark);
- NODE_INFO (node)->dirty = TRUE;
+ node_prepend_ui_reference (node, ctx->merge_id, action_quark);
raise_error = FALSE;
}
if (action != NULL)
action_quark = g_quark_from_string (action);
- node_prepend_ui_reference (NODE_INFO (child),
- merge_id, action_quark);
+ node_prepend_ui_reference (child, merge_id, action_quark);
if (NODE_INFO (child)->action_name == 0)
NODE_INFO (child)->action_name = action_quark;
- NODE_INFO (child)->dirty = TRUE;
-
queue_update (self);
g_object_notify (G_OBJECT (self), "ui");
{
guint merge_id = GPOINTER_TO_UINT (user_data);
- node_remove_ui_reference (NODE_INFO (node), merge_id);
+ node_remove_ui_reference (node, merge_id);
return FALSE; /* continue */
}
if (GTK_IS_MENU_ITEM (item))
_gtk_action_sync_menu_visible (NULL, item, empty);
if (GTK_IS_WIDGET (filler))
- g_object_set (G_OBJECT (filler), "visible", empty, NULL);
+ {
+ if (empty)
+ gtk_widget_show (filler);
+ else
+ gtk_widget_hide (filler);
+ }
}
g_list_free (children);
#ifdef DEBUG_UI_MANAGER
GList *tmp;
#endif
-
+
g_return_if_fail (node != NULL);
g_return_if_fail (NODE_INFO (node) != NULL);
info = NODE_INFO (node);
+
+ if (!info->dirty)
+ return;
in_popup = in_popup || (info->type == NODE_TYPE_POPUP);
g_print (")\n");
#endif
- if (info->dirty)
+ const gchar *action_name;
+ NodeUIReference *ref;
+
+ if (info->uifiles == NULL) {
+ /* We may need to remove this node.
+ * This must be done in post order
+ */
+ goto recurse_children;
+ }
+
+ ref = info->uifiles->data;
+ action_name = g_quark_to_string (ref->action_quark);
+ action = get_action_by_name (self, action_name);
+
+ info->dirty = FALSE;
+
+ /* Check if the node doesn't have an action and must have an action */
+ if (action == NULL &&
+ info->type != NODE_TYPE_ROOT &&
+ info->type != NODE_TYPE_MENUBAR &&
+ info->type != NODE_TYPE_TOOLBAR &&
+ info->type != NODE_TYPE_POPUP &&
+ info->type != NODE_TYPE_SEPARATOR &&
+ info->type != NODE_TYPE_MENU_PLACEHOLDER &&
+ info->type != NODE_TYPE_TOOLBAR_PLACEHOLDER)
{
- const gchar *action_name;
- NodeUIReference *ref;
-
- if (info->uifiles == NULL) {
- /* We may need to remove this node.
- * This must be done in post order
- */
- goto recurse_children;
- }
-
- ref = info->uifiles->data;
- action_name = g_quark_to_string (ref->action_quark);
- action = get_action_by_name (self, action_name);
-
- info->dirty = FALSE;
-
- /* Check if the node doesn't have an action and must have an action */
- if (action == NULL &&
- info->type != NODE_TYPE_ROOT &&
- info->type != NODE_TYPE_MENUBAR &&
- info->type != NODE_TYPE_TOOLBAR &&
- info->type != NODE_TYPE_POPUP &&
- info->type != NODE_TYPE_SEPARATOR &&
- info->type != NODE_TYPE_MENU_PLACEHOLDER &&
- info->type != NODE_TYPE_TOOLBAR_PLACEHOLDER)
- {
- g_warning ("%s: missing action", info->name);
-
- goto recurse_children;
- }
-
- if (action)
- gtk_action_set_accel_group (action, self->private_data->accel_group);
-
- /* If the widget already has a proxy and the action hasn't changed, then
- * we only have to update the tearoff menu items.
- */
- if (info->proxy != NULL && action == info->action)
+ g_warning ("%s: missing action", info->name);
+
+ goto recurse_children;
+ }
+
+ if (action)
+ gtk_action_set_accel_group (action, self->private_data->accel_group);
+
+ /* If the widget already has a proxy and the action hasn't changed, then
+ * we only have to update the tearoff menu items.
+ */
+ if (info->proxy != NULL && action == info->action)
+ {
+ if (info->type == NODE_TYPE_MENU)
{
- if (info->type == NODE_TYPE_MENU)
- {
- GtkWidget *menu;
- GList *siblings;
-
- menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (info->proxy));
- siblings = gtk_container_get_children (GTK_CONTAINER (menu));
- if (siblings != NULL && GTK_IS_TEAROFF_MENU_ITEM (siblings->data))
- g_object_set (G_OBJECT (siblings->data),
- "visible", self->private_data->add_tearoffs && !in_popup,
- NULL);
- g_list_free (siblings);
- }
-
- goto recurse_children;
+ GtkWidget *menu;
+ GList *siblings;
+
+ menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (info->proxy));
+ siblings = gtk_container_get_children (GTK_CONTAINER (menu));
+ if (siblings != NULL && GTK_IS_TEAROFF_MENU_ITEM (siblings->data))
+ g_object_set (G_OBJECT (siblings->data),
+ "visible", self->private_data->add_tearoffs && !in_popup,
+ NULL);
+ g_list_free (siblings);
}
- switch (info->type)
+ goto recurse_children;
+ }
+
+ switch (info->type)
+ {
+ case NODE_TYPE_MENUBAR:
+ if (info->proxy == NULL)
{
- case NODE_TYPE_MENUBAR:
- if (info->proxy == NULL)
- {
- info->proxy = gtk_menu_bar_new ();
- g_object_ref (info->proxy);
- gtk_object_sink (GTK_OBJECT (info->proxy));
- gtk_widget_set_name (info->proxy, info->name);
- gtk_widget_show (info->proxy);
- g_signal_emit (self, ui_manager_signals[ADD_WIDGET], 0, info->proxy);
- }
- break;
- case NODE_TYPE_POPUP:
- if (info->proxy == NULL)
- {
- info->proxy = gtk_menu_new ();
- g_object_ref (info->proxy);
- gtk_object_sink (GTK_OBJECT (info->proxy));
- }
+ info->proxy = gtk_menu_bar_new ();
+ g_object_ref (info->proxy);
+ gtk_object_sink (GTK_OBJECT (info->proxy));
gtk_widget_set_name (info->proxy, info->name);
- break;
- case NODE_TYPE_MENU:
+ gtk_widget_show (info->proxy);
+ g_signal_emit (self, ui_manager_signals[ADD_WIDGET], 0, info->proxy);
+ }
+ break;
+ case NODE_TYPE_POPUP:
+ if (info->proxy == NULL)
+ {
+ info->proxy = gtk_menu_new ();
+ g_object_ref (info->proxy);
+ gtk_object_sink (GTK_OBJECT (info->proxy));
+ }
+ gtk_widget_set_name (info->proxy, info->name);
+ break;
+ case NODE_TYPE_MENU:
+ {
+ GtkWidget *prev_submenu = NULL;
+ GtkWidget *menu;
+ GList *siblings;
+ /* remove the proxy if it is of the wrong type ... */
+ if (info->proxy &&
+ G_OBJECT_TYPE (info->proxy) != GTK_ACTION_GET_CLASS (action)->menu_item_type)
{
- GtkWidget *prev_submenu = NULL;
- GtkWidget *menu;
- GList *siblings;
- /* remove the proxy if it is of the wrong type ... */
- if (info->proxy &&
- G_OBJECT_TYPE (info->proxy) != GTK_ACTION_GET_CLASS (action)->menu_item_type)
+ prev_submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (info->proxy));
+ if (prev_submenu)
{
- prev_submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (info->proxy));
- if (prev_submenu)
- {
- g_object_ref (prev_submenu);
- gtk_menu_item_set_submenu (GTK_MENU_ITEM (info->proxy), NULL);
- }
- gtk_action_disconnect_proxy (info->action, info->proxy);
- gtk_container_remove (GTK_CONTAINER (info->proxy->parent),
- info->proxy);
- g_object_unref (info->proxy);
- info->proxy = NULL;
+ g_object_ref (prev_submenu);
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (info->proxy), NULL);
}
- /* create proxy if needed ... */
- if (info->proxy == NULL)
+ gtk_action_disconnect_proxy (info->action, info->proxy);
+ gtk_container_remove (GTK_CONTAINER (info->proxy->parent),
+ info->proxy);
+ g_object_unref (info->proxy);
+ info->proxy = NULL;
+ }
+ /* create proxy if needed ... */
+ if (info->proxy == NULL)
+ {
+ GtkWidget *menushell;
+ gint pos;
+
+ if (find_menu_position (node, &menushell, &pos))
{
- GtkWidget *menushell;
- gint pos;
+ GtkWidget *tearoff;
+ GtkWidget *filler;
- if (find_menu_position (node, &menushell, &pos))
- {
- GtkWidget *tearoff;
- GtkWidget *filler;
-
- info->proxy = gtk_action_create_menu_item (action);
- g_object_ref (info->proxy);
- gtk_object_sink (GTK_OBJECT (info->proxy));
- menu = gtk_menu_new ();
- gtk_widget_set_name (info->proxy, info->name);
- gtk_widget_set_name (menu, info->name);
- tearoff = gtk_tearoff_menu_item_new ();
- gtk_widget_set_no_show_all (tearoff, TRUE);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), tearoff);
- filler = gtk_menu_item_new_with_label (_("Empty"));
- g_object_set_data (G_OBJECT (filler),
- "gtk-empty-menu-item",
- GINT_TO_POINTER (TRUE));
- gtk_widget_set_sensitive (filler, FALSE);
- gtk_widget_set_no_show_all (filler, TRUE);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), filler);
- gtk_menu_item_set_submenu (GTK_MENU_ITEM (info->proxy), menu);
- gtk_menu_shell_insert (GTK_MENU_SHELL (menushell), info->proxy, pos);
- g_signal_connect (info->proxy, "notify::visible",
- G_CALLBACK (update_smart_separators), NULL);
- }
- }
- else
- gtk_action_connect_proxy (action, info->proxy);
-
- if (prev_submenu)
- {
- gtk_menu_item_set_submenu (GTK_MENU_ITEM (info->proxy),
- prev_submenu);
- g_object_unref (prev_submenu);
+ info->proxy = gtk_action_create_menu_item (action);
+ g_object_ref (info->proxy);
+ gtk_object_sink (GTK_OBJECT (info->proxy));
+ menu = gtk_menu_new ();
+ gtk_widget_set_name (info->proxy, info->name);
+ gtk_widget_set_name (menu, info->name);
+ tearoff = gtk_tearoff_menu_item_new ();
+ gtk_widget_set_no_show_all (tearoff, TRUE);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), tearoff);
+ filler = gtk_menu_item_new_with_label (_("Empty"));
+ g_object_set_data (G_OBJECT (filler),
+ "gtk-empty-menu-item",
+ GINT_TO_POINTER (TRUE));
+ gtk_widget_set_sensitive (filler, FALSE);
+ gtk_widget_set_no_show_all (filler, TRUE);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), filler);
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (info->proxy), menu);
+ gtk_menu_shell_insert (GTK_MENU_SHELL (menushell), info->proxy, pos);
+ g_signal_connect (info->proxy, "notify::visible",
+ G_CALLBACK (update_smart_separators), NULL);
}
- menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (info->proxy));
- siblings = gtk_container_get_children (GTK_CONTAINER (menu));
- if (siblings != NULL && GTK_IS_TEAROFF_MENU_ITEM (siblings->data))
- g_object_set (G_OBJECT (siblings->data),
- "visible", self->private_data->add_tearoffs && !in_popup,
- NULL);
- g_list_free (siblings);
}
- break;
- case NODE_TYPE_UNDECIDED:
- g_warning ("found undecided node!");
- break;
- case NODE_TYPE_ROOT:
- break;
- case NODE_TYPE_TOOLBAR:
- if (info->proxy == NULL)
- {
- info->proxy = gtk_toolbar_new ();
- g_object_ref (info->proxy);
- gtk_object_sink (GTK_OBJECT (info->proxy));
- gtk_widget_set_name (info->proxy, info->name);
- gtk_widget_show (info->proxy);
- g_signal_emit (self, ui_manager_signals[ADD_WIDGET], 0, info->proxy);
- }
- break;
- case NODE_TYPE_MENU_PLACEHOLDER:
- /* create menu items for placeholders if necessary ... */
- if (!GTK_IS_SEPARATOR_MENU_ITEM (info->proxy) ||
- !GTK_IS_SEPARATOR_MENU_ITEM (info->extra))
+ else
+ gtk_action_connect_proxy (action, info->proxy);
+
+ if (prev_submenu)
+ {
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (info->proxy),
+ prev_submenu);
+ g_object_unref (prev_submenu);
+ }
+ menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (info->proxy));
+ siblings = gtk_container_get_children (GTK_CONTAINER (menu));
+ if (siblings != NULL && GTK_IS_TEAROFF_MENU_ITEM (siblings->data))
+ g_object_set (G_OBJECT (siblings->data),
+ "visible", self->private_data->add_tearoffs && !in_popup,
+ NULL);
+ g_list_free (siblings);
+ }
+ break;
+ case NODE_TYPE_UNDECIDED:
+ g_warning ("found undecided node!");
+ break;
+ case NODE_TYPE_ROOT:
+ break;
+ case NODE_TYPE_TOOLBAR:
+ if (info->proxy == NULL)
+ {
+ info->proxy = gtk_toolbar_new ();
+ g_object_ref (info->proxy);
+ gtk_object_sink (GTK_OBJECT (info->proxy));
+ gtk_widget_set_name (info->proxy, info->name);
+ gtk_widget_show (info->proxy);
+ g_signal_emit (self, ui_manager_signals[ADD_WIDGET], 0, info->proxy);
+ }
+ break;
+ case NODE_TYPE_MENU_PLACEHOLDER:
+ /* create menu items for placeholders if necessary ... */
+ if (!GTK_IS_SEPARATOR_MENU_ITEM (info->proxy) ||
+ !GTK_IS_SEPARATOR_MENU_ITEM (info->extra))
+ {
+ if (info->proxy)
{
- if (info->proxy)
- {
- gtk_container_remove (GTK_CONTAINER (info->proxy->parent),
- info->proxy);
- g_object_unref (info->proxy);
- info->proxy = NULL;
- }
- if (info->extra)
- {
- gtk_container_remove (GTK_CONTAINER (info->extra->parent),
- info->extra);
- g_object_unref (info->extra);
- info->extra = NULL;
- }
+ gtk_container_remove (GTK_CONTAINER (info->proxy->parent),
+ info->proxy);
+ g_object_unref (info->proxy);
+ info->proxy = NULL;
}
- if (info->proxy == NULL)
+ if (info->extra)
{
- GtkWidget *menushell;
- gint pos;
-
- if (find_menu_position (node, &menushell, &pos))
- {
- info->proxy = gtk_separator_menu_item_new ();
- g_object_ref (info->proxy);
- gtk_object_sink (GTK_OBJECT (info->proxy));
- g_object_set_data (G_OBJECT (info->proxy),
- "gtk-separator-mode",
- GINT_TO_POINTER (SEPARATOR_MODE_HIDDEN));
- gtk_widget_set_no_show_all (info->proxy, TRUE);
- gtk_menu_shell_insert (GTK_MENU_SHELL (menushell),
- NODE_INFO (node)->proxy, pos);
-
- info->extra = gtk_separator_menu_item_new ();
- g_object_ref (info->extra);
- gtk_object_sink (GTK_OBJECT (info->extra));
- g_object_set_data (G_OBJECT (info->extra),
- "gtk-separator-mode",
- GINT_TO_POINTER (SEPARATOR_MODE_HIDDEN));
- gtk_widget_set_no_show_all (info->extra, TRUE);
- gtk_menu_shell_insert (GTK_MENU_SHELL (menushell),
- NODE_INFO (node)->extra, pos+1);
- }
+ gtk_container_remove (GTK_CONTAINER (info->extra->parent),
+ info->extra);
+ g_object_unref (info->extra);
+ info->extra = NULL;
}
- break;
- case NODE_TYPE_TOOLBAR_PLACEHOLDER:
- /* create toolbar items for placeholders if necessary ... */
- if (!GTK_IS_SEPARATOR_TOOL_ITEM (info->proxy) ||
- !GTK_IS_SEPARATOR_TOOL_ITEM (info->extra))
- {
- if (info->proxy)
- {
- gtk_container_remove (GTK_CONTAINER (info->proxy->parent),
- info->proxy);
- g_object_unref (info->proxy);
- info->proxy = NULL;
- }
- if (info->extra)
- {
- gtk_container_remove (GTK_CONTAINER (info->extra->parent),
- info->extra);
- g_object_unref (info->extra);
- info->extra = NULL;
- }
- }
- if (info->proxy == NULL)
+ }
+ if (info->proxy == NULL)
+ {
+ GtkWidget *menushell;
+ gint pos;
+
+ if (find_menu_position (node, &menushell, &pos))
{
- GtkWidget *toolbar;
- gint pos;
-
- if (find_toolbar_position (node, &toolbar, &pos))
- {
- GtkToolItem *item;
-
- item = gtk_separator_tool_item_new ();
- gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, pos);
- info->proxy = GTK_WIDGET (item);
- g_object_ref (info->proxy);
- gtk_object_sink (GTK_OBJECT (info->proxy));
- g_object_set_data (G_OBJECT (info->proxy),
- "gtk-separator-mode",
- GINT_TO_POINTER (SEPARATOR_MODE_HIDDEN));
- gtk_widget_set_no_show_all (info->proxy, TRUE);
-
- item = gtk_separator_tool_item_new ();
- gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, pos+1);
- info->extra = GTK_WIDGET (item);
- g_object_ref (info->extra);
- gtk_object_sink (GTK_OBJECT (info->extra));
- g_object_set_data (G_OBJECT (info->extra),
- "gtk-separator-mode",
- GINT_TO_POINTER (SEPARATOR_MODE_HIDDEN));
- gtk_widget_set_no_show_all (info->extra, TRUE);
- }
+ info->proxy = gtk_separator_menu_item_new ();
+ g_object_ref (info->proxy);
+ gtk_object_sink (GTK_OBJECT (info->proxy));
+ g_object_set_data (G_OBJECT (info->proxy),
+ "gtk-separator-mode",
+ GINT_TO_POINTER (SEPARATOR_MODE_HIDDEN));
+ gtk_widget_set_no_show_all (info->proxy, TRUE);
+ gtk_menu_shell_insert (GTK_MENU_SHELL (menushell),
+ NODE_INFO (node)->proxy, pos);
+
+ info->extra = gtk_separator_menu_item_new ();
+ g_object_ref (info->extra);
+ gtk_object_sink (GTK_OBJECT (info->extra));
+ g_object_set_data (G_OBJECT (info->extra),
+ "gtk-separator-mode",
+ GINT_TO_POINTER (SEPARATOR_MODE_HIDDEN));
+ gtk_widget_set_no_show_all (info->extra, TRUE);
+ gtk_menu_shell_insert (GTK_MENU_SHELL (menushell),
+ NODE_INFO (node)->extra, pos+1);
}
- break;
- case NODE_TYPE_MENUITEM:
- /* remove the proxy if it is of the wrong type ... */
- if (info->proxy &&
- G_OBJECT_TYPE (info->proxy) != GTK_ACTION_GET_CLASS (action)->menu_item_type)
+ }
+ break;
+ case NODE_TYPE_TOOLBAR_PLACEHOLDER:
+ /* create toolbar items for placeholders if necessary ... */
+ if (!GTK_IS_SEPARATOR_TOOL_ITEM (info->proxy) ||
+ !GTK_IS_SEPARATOR_TOOL_ITEM (info->extra))
+ {
+ if (info->proxy)
{
- g_signal_handlers_disconnect_by_func (info->proxy,
- G_CALLBACK (update_smart_separators),
- NULL);
- gtk_action_disconnect_proxy (info->action, info->proxy);
gtk_container_remove (GTK_CONTAINER (info->proxy->parent),
info->proxy);
g_object_unref (info->proxy);
info->proxy = NULL;
}
- /* create proxy if needed ... */
- if (info->proxy == NULL)
+ if (info->extra)
{
- GtkWidget *menushell;
- gint pos;
-
- if (find_menu_position (node, &menushell, &pos))
- {
- info->proxy = gtk_action_create_menu_item (action);
- g_object_ref (info->proxy);
- gtk_object_sink (GTK_OBJECT (info->proxy));
- gtk_widget_set_name (info->proxy, info->name);
-
- gtk_menu_shell_insert (GTK_MENU_SHELL (menushell),
- info->proxy, pos);
- }
+ gtk_container_remove (GTK_CONTAINER (info->extra->parent),
+ info->extra);
+ g_object_unref (info->extra);
+ info->extra = NULL;
}
- else
+ }
+ if (info->proxy == NULL)
+ {
+ GtkWidget *toolbar;
+ gint pos;
+
+ if (find_toolbar_position (node, &toolbar, &pos))
{
- g_signal_handlers_disconnect_by_func (info->proxy,
- G_CALLBACK (update_smart_separators),
- NULL);
- gtk_menu_item_set_submenu (GTK_MENU_ITEM (info->proxy), NULL);
- gtk_action_connect_proxy (action, info->proxy);
+ GtkToolItem *item;
+
+ item = gtk_separator_tool_item_new ();
+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, pos);
+ info->proxy = GTK_WIDGET (item);
+ g_object_ref (info->proxy);
+ gtk_object_sink (GTK_OBJECT (info->proxy));
+ g_object_set_data (G_OBJECT (info->proxy),
+ "gtk-separator-mode",
+ GINT_TO_POINTER (SEPARATOR_MODE_HIDDEN));
+ gtk_widget_set_no_show_all (info->proxy, TRUE);
+
+ item = gtk_separator_tool_item_new ();
+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, pos+1);
+ info->extra = GTK_WIDGET (item);
+ g_object_ref (info->extra);
+ gtk_object_sink (GTK_OBJECT (info->extra));
+ g_object_set_data (G_OBJECT (info->extra),
+ "gtk-separator-mode",
+ GINT_TO_POINTER (SEPARATOR_MODE_HIDDEN));
+ gtk_widget_set_no_show_all (info->extra, TRUE);
}
- g_signal_connect (info->proxy, "notify::visible",
- G_CALLBACK (update_smart_separators), NULL);
- if (in_popup)
+ }
+ break;
+ case NODE_TYPE_MENUITEM:
+ /* remove the proxy if it is of the wrong type ... */
+ if (info->proxy &&
+ G_OBJECT_TYPE (info->proxy) != GTK_ACTION_GET_CLASS (action)->menu_item_type)
+ {
+ g_signal_handlers_disconnect_by_func (info->proxy,
+ G_CALLBACK (update_smart_separators),
+ NULL);
+ gtk_action_disconnect_proxy (info->action, info->proxy);
+ gtk_container_remove (GTK_CONTAINER (info->proxy->parent),
+ info->proxy);
+ g_object_unref (info->proxy);
+ info->proxy = NULL;
+ }
+ /* create proxy if needed ... */
+ if (info->proxy == NULL)
+ {
+ GtkWidget *menushell;
+ gint pos;
+
+ if (find_menu_position (node, &menushell, &pos))
{
- /* don't show accels in popups */
- GtkWidget *label = GTK_BIN (info->proxy)->child;
- g_object_set (G_OBJECT (label),
- "accel_closure", NULL,
- NULL);
+ info->proxy = gtk_action_create_menu_item (action);
+ g_object_ref (info->proxy);
+ gtk_object_sink (GTK_OBJECT (info->proxy));
+ gtk_widget_set_name (info->proxy, info->name);
+
+ gtk_menu_shell_insert (GTK_MENU_SHELL (menushell),
+ info->proxy, pos);
}
-
- break;
- case NODE_TYPE_TOOLITEM:
- /* remove the proxy if it is of the wrong type ... */
- if (info->proxy &&
- G_OBJECT_TYPE (info->proxy) != GTK_ACTION_GET_CLASS (action)->toolbar_item_type)
+ }
+ else
+ {
+ g_signal_handlers_disconnect_by_func (info->proxy,
+ G_CALLBACK (update_smart_separators),
+ NULL);
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (info->proxy), NULL);
+ gtk_action_connect_proxy (action, info->proxy);
+ }
+ g_signal_connect (info->proxy, "notify::visible",
+ G_CALLBACK (update_smart_separators), NULL);
+ if (in_popup)
+ {
+ /* don't show accels in popups */
+ GtkWidget *label = GTK_BIN (info->proxy)->child;
+ g_object_set (G_OBJECT (label),
+ "accel_closure", NULL,
+ NULL);
+ }
+
+ break;
+ case NODE_TYPE_TOOLITEM:
+ /* remove the proxy if it is of the wrong type ... */
+ if (info->proxy &&
+ G_OBJECT_TYPE (info->proxy) != GTK_ACTION_GET_CLASS (action)->toolbar_item_type)
+ {
+ g_signal_handlers_disconnect_by_func (info->proxy,
+ G_CALLBACK (update_smart_separators),
+ NULL);
+ gtk_action_disconnect_proxy (info->action, info->proxy);
+ gtk_container_remove (GTK_CONTAINER (info->proxy->parent),
+ info->proxy);
+ g_object_unref (info->proxy);
+ info->proxy = NULL;
+ }
+ /* create proxy if needed ... */
+ if (info->proxy == NULL)
+ {
+ GtkWidget *toolbar;
+ gint pos;
+
+ if (find_toolbar_position (node, &toolbar, &pos))
+ {
+ info->proxy = gtk_action_create_tool_item (action);
+ g_object_ref (info->proxy);
+ gtk_object_sink (GTK_OBJECT (info->proxy));
+ gtk_widget_set_name (info->proxy, info->name);
+
+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar),
+ GTK_TOOL_ITEM (info->proxy), pos);
+
+ /* FIXME: we must trigger the notify::tooltip handler, since
+ * tooltips on toolitems can't be set before the toolitem
+ * is added to the toolbar.
+ */
+ g_object_get (G_OBJECT (action), "tooltip", &tooltip, NULL);
+ g_object_set (G_OBJECT (action), "tooltip", tooltip, NULL);
+ g_free (tooltip);
+ }
+ }
+ else
+ {
+ g_signal_handlers_disconnect_by_func (info->proxy,
+ G_CALLBACK (update_smart_separators),
+ NULL);
+ gtk_action_connect_proxy (action, info->proxy);
+ }
+ g_signal_connect (info->proxy, "notify::visible",
+ G_CALLBACK (update_smart_separators), NULL);
+ break;
+ case NODE_TYPE_SEPARATOR:
+ if (NODE_INFO (node->parent)->type == NODE_TYPE_TOOLBAR ||
+ NODE_INFO (node->parent)->type == NODE_TYPE_TOOLBAR_PLACEHOLDER)
+ {
+ GtkWidget *toolbar;
+ gint pos;
+
+ if (GTK_IS_SEPARATOR_TOOL_ITEM (info->proxy))
{
- g_signal_handlers_disconnect_by_func (info->proxy,
- G_CALLBACK (update_smart_separators),
- NULL);
- gtk_action_disconnect_proxy (info->action, info->proxy);
gtk_container_remove (GTK_CONTAINER (info->proxy->parent),
info->proxy);
g_object_unref (info->proxy);
info->proxy = NULL;
}
- /* create proxy if needed ... */
- if (info->proxy == NULL)
- {
- GtkWidget *toolbar;
- gint pos;
-
- if (find_toolbar_position (node, &toolbar, &pos))
- {
- info->proxy = gtk_action_create_tool_item (action);
- g_object_ref (info->proxy);
- gtk_object_sink (GTK_OBJECT (info->proxy));
- gtk_widget_set_name (info->proxy, info->name);
-
- gtk_toolbar_insert (GTK_TOOLBAR (toolbar),
- GTK_TOOL_ITEM (info->proxy), pos);
-
- /* FIXME: we must trigger the notify::tooltip handler, since
- * tooltips on toolitems can't be set before the toolitem
- * is added to the toolbar.
- */
- g_object_get (G_OBJECT (action), "tooltip", &tooltip, NULL);
- g_object_set (G_OBJECT (action), "tooltip", tooltip, NULL);
- g_free (tooltip);
- }
- }
- else
+
+ if (find_toolbar_position (node, &toolbar, &pos))
{
- g_signal_handlers_disconnect_by_func (info->proxy,
- G_CALLBACK (update_smart_separators),
- NULL);
- gtk_action_connect_proxy (action, info->proxy);
+ GtkToolItem *item = gtk_separator_tool_item_new ();
+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, pos);
+ info->proxy = GTK_WIDGET (item);
+ g_object_ref (info->proxy);
+ gtk_object_sink (GTK_OBJECT (info->proxy));
+ gtk_widget_set_no_show_all (info->proxy, TRUE);
+ g_object_set_data (G_OBJECT (info->proxy),
+ "gtk-separator-mode",
+ GINT_TO_POINTER (SEPARATOR_MODE_SMART));
+ gtk_widget_show (info->proxy);
}
- g_signal_connect (info->proxy, "notify::visible",
- G_CALLBACK (update_smart_separators), NULL);
- break;
- case NODE_TYPE_SEPARATOR:
- if (NODE_INFO (node->parent)->type == NODE_TYPE_TOOLBAR ||
- NODE_INFO (node->parent)->type == NODE_TYPE_TOOLBAR_PLACEHOLDER)
+ }
+ else
+ {
+ GtkWidget *menushell;
+ gint pos;
+
+ if (GTK_IS_SEPARATOR_MENU_ITEM (info->proxy))
{
- GtkWidget *toolbar;
- gint pos;
-
- if (GTK_IS_SEPARATOR_TOOL_ITEM (info->proxy))
- {
- gtk_container_remove (GTK_CONTAINER (info->proxy->parent),
- info->proxy);
- g_object_unref (info->proxy);
- info->proxy = NULL;
- }
-
- if (find_toolbar_position (node, &toolbar, &pos))
- {
- GtkToolItem *item = gtk_separator_tool_item_new ();
- gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, pos);
- info->proxy = GTK_WIDGET (item);
- g_object_ref (info->proxy);
- gtk_object_sink (GTK_OBJECT (info->proxy));
- gtk_widget_set_no_show_all (info->proxy, TRUE);
- g_object_set_data (G_OBJECT (info->proxy),
- "gtk-separator-mode",
- GINT_TO_POINTER (SEPARATOR_MODE_SMART));
- gtk_widget_show (info->proxy);
- }
+ gtk_container_remove (GTK_CONTAINER (info->proxy->parent),
+ info->proxy);
+ g_object_unref (info->proxy);
+ info->proxy = NULL;
}
- else
+
+ if (find_menu_position (node, &menushell, &pos))
{
- GtkWidget *menushell;
- gint pos;
-
- if (GTK_IS_SEPARATOR_MENU_ITEM (info->proxy))
- {
- gtk_container_remove (GTK_CONTAINER (info->proxy->parent),
- info->proxy);
- g_object_unref (info->proxy);
- info->proxy = NULL;
- }
-
- if (find_menu_position (node, &menushell, &pos))
- {
- info->proxy = gtk_separator_menu_item_new ();
- g_object_ref (info->proxy);
- gtk_object_sink (GTK_OBJECT (info->proxy));
- gtk_widget_set_no_show_all (info->proxy, TRUE);
- g_object_set_data (G_OBJECT (info->proxy),
- "gtk-separator-mode",
- GINT_TO_POINTER (SEPARATOR_MODE_SMART));
- gtk_menu_shell_insert (GTK_MENU_SHELL (menushell),
- info->proxy, pos);
- gtk_widget_show (info->proxy);
- }
+ info->proxy = gtk_separator_menu_item_new ();
+ g_object_ref (info->proxy);
+ gtk_object_sink (GTK_OBJECT (info->proxy));
+ gtk_widget_set_no_show_all (info->proxy, TRUE);
+ g_object_set_data (G_OBJECT (info->proxy),
+ "gtk-separator-mode",
+ GINT_TO_POINTER (SEPARATOR_MODE_SMART));
+ gtk_menu_shell_insert (GTK_MENU_SHELL (menushell),
+ info->proxy, pos);
+ gtk_widget_show (info->proxy);
}
- break;
- case NODE_TYPE_ACCELERATOR:
- gtk_action_connect_accelerator (action);
- break;
}
-
- if (action)
- g_object_ref (action);
- if (info->action)
- g_object_unref (info->action);
- info->action = action;
+ break;
+ case NODE_TYPE_ACCELERATOR:
+ gtk_action_connect_accelerator (action);
+ break;
}
+
+ if (action)
+ g_object_ref (action);
+ if (info->action)
+ g_object_unref (info->action);
+ info->action = action;
recurse_children:
/* process children */
while (child)
{
GNode *current;
-
+
current = child;
child = current->next;
update_node (self, current, in_popup);
}
-
+
if (info->proxy)
{
if (info->type == NODE_TYPE_MENU)
else if (info->type == NODE_TYPE_TOOLBAR || info->type == NODE_TYPE_POPUP)
update_smart_separators (info->proxy);
}
-
+
/* handle cleanup of dead nodes */
if (node->children == NULL && info->uifiles == NULL)
{
queue_update (self);
}
+static void
+mark_node_dirty (GNode *node)
+{
+ GNode *p;
+
+ /* FIXME could optimize this */
+ for (p = node; p; p = p->parent)
+ NODE_INFO (p)->dirty = TRUE;
+}
+
static const gchar *open_tag_format[] = {
"%*s<UNDECIDED",
"%*s<ui",